/*
 * 颜色集合
 */
define("color", function() {
	var color = {
		white: "#ffffff",
		ashen: "#d9d6c3",
		silver: "#a1a3a6",
		gray: "#555555",
		black: "#21242b",
		red: "#e51400",
		crimson: "#a20025",
		green: "#60a917",
		blue: "#00aff0",
		yellow: "#e3c800",
		yellowish: "#dec674",
		gold: "#fffcb0",
		orange: "#fa6800",
		apricot: "#fab27b",
		brownness: "#843900",
		colormoment: "#f7acbc",
		cherry: "#feeeed",
		roseous: "#f05b72",
		redplum: "#f69c9f",
		lime: "#a4c400",
		whitegreen: "#cde6c7",
		inst: "#90d7ec",
		cyan: "#1ba1e2",
		emerald: "#008a00",
		teal: "#00aba9",
		cobalt: "#0050ef",
		indigo: "#6a00ff",
		violet: "#aa00ff",
		pink: "#dc4fad",
		magenta: "#d80073",
		amber: "#f0a30a",
		brown: "#825a2c",
		olive: "#6d8764",
		steel: "#647687",
		mauve: "#76608a",
		taupe: "#87794e",
		dark: "#333333",
		darker: "#222222",
		darkBrown: "#63362f",
		darkCrimson: "#640024",
		darkMagenta: "#81003c",
		darkIndigo: "#4b0096",
		darkCyan: "#1b6eae",
		darkCobalt: "#00356a",
		darkTeal: "#004050",
		darkEmerald: "#003e00",
		darkGreen: "#128023",
		darkOrange: "#bf5a15",
		darkRed: "#9a1616",
		darkPink: "#9a165a",
		darkViolet: "#57169a",
		darkBlue: "#16499a",
		lightBlue: "#4390df",
		lightRed: "#ff2d19",
		lightGreen: "#7ad61d",
		lighterBlue: "#00ccff",
		lightTeal: "#45fffd",
		lightOlive: "#78aa1c",
		lightOrange: "#c29008",
		lightPink: "#f472d0",
		grayDark: "#333333",
		grayDarker: "#222222",
		grayLight: "#999999",
		grayLighter: "#eeeeee",
		ink: "#464547",
		lightWhite: "#f6f5ec"
	};
	color.error = "#a20025"
	color.warn = "#fa6800"
	color.success = "#60a917"
	color.info = "#1ba1e2"
	return color;
});
/*
 * document.title
 */
define("title", function() {
	return function(title) {
		title === undefined && (title = document.title);
		var bus_name = window.appConfig && appConfig.site_info && appConfig.site_info.info.title;
		if (bus_name && title.indexOf(bus_name) === -1) {
			document.title = title + (title ? ("-" + bus_name) : bus_name);
		} else {
			document.title = title
		}
	}
});
/*浏览器判断工具*/
define("browser", function() {
	var tool = {
		isMobile: isMobile
	}
	return tool;
});
/*
 * queryString处理工具
 */
;
(function() {
	define("queryString", function() {
		function QueryString(url) {
			if (!(this instanceof QueryString)) {
				return new QueryString(url)
			}
			this.init(url);
		};
		QueryString.prototype = {
			init: function(url) {
				url || (url = location.search);
				var queryStr = url.substr(url.indexOf("?") + 1);
				this._init_queryStr(queryStr);
			},
			_init_queryStr: function(queryStr) {
				var queryList = queryStr.split("&");
				var queryHash = {};
				for (var i = 0, queryInfo, len = queryList.length; i < len; i += 1) {
					if (queryInfo = queryList[i]) {
						queryInfo = queryInfo.split("=");
						if (queryInfo[1]) {
							queryHash[queryInfo[0]] = decodeURIComponent(queryInfo[1]);
						}
					}
				}
				this.queryHash = queryHash;
			},
			get: function(key) {
				var queryHash = this.queryHash || {};
				return queryHash[key];
			},
			set: function(key, value) {
				var queryHash = this.queryHash || (this.queryHash = {});
				queryHash[key] = value;
			},
			toSting: function(origin) {
				origin || (origin = location.origin);
				var queryHash = this.queryHash || {};
				var queryStr = "";
				for (var key in queryHash) {
					if (queryHash.hasOwnProperty(key)) {
						queryStr += (key + "=" + encodeURIComponent(queryHash[key]));
					}
				}
				var url = origin + "?" + queryStr;
			}
		}
		return QueryString;
	});
	/*
	 * 数据核心工具，用于处理数据
	 */
	;
	(function() {
		/*
		 * 数据解析工具
		 */
		var dataFormat = function(success, error) {
			error || (error = dataFormat.errorHandle);
			return function(data, textStatus, jqXHR) {
				switch (data.type) {
					case "json":
						try {
							var result = $.parseJSON(data.toString);
						} catch (e) {
							data.error = e;
							error.call(this, "JSON Parse Error" /*解析错误*/ , jqXHR);
							return;
						}
						data.result = result;
						success.apply(this, arguments);
						break;
					case "string":
						data.result = data.toString;
						success.apply(this, arguments);
						break;
					case "html":
						data.result = jQuery(data.toString);
						success.apply(this, arguments);
						break;
					case "template":
						data.result = jSouper.parse(data.toString);
						success.apply(this, arguments);
						break;
					case "error":
						// data.error = result;
						var result = $.parseJSON(data.toString);
						error.call(this, result.errorCode, jqXHR, result.errorMsg, data)
						break;
					default: //JSON without error
						try {
							var result = $.parseJSON(data.toString);
						} catch (e) {}
						data.result = result;
						success.apply(this, arguments);
						break;
				}
			}
		};
		dataFormat.errorHandle = function(errorCode, xhr, errorMsg) {
			console.log(errorCode, xhr);
			alert("error", errorMsg);
		};
		define("dataFormat", function() {
			return dataFormat
		});
		//判断是否支持跨域
		function can_co(method, url) {
			var result = false;
			if (window.XMLHttpRequest && "withCredentials" in (new XMLHttpRequest)) {
				result = true;
			}
			return result
		}
		if (can_co()) { //老旧浏览器的数据请求解决方案
			/*
			 * 基于jQ的跨域ajax工具函数
			 */
			define("coAjax", ["jQuery", "eventManager"], function($, eventManager) {
				//进度条的注入
				//is onprogress supported by browser?
				var hasOnProgress = ("onprogress" in $.ajaxSettings.xhr());

				//If not supported, do nothing
				if (hasOnProgress) {
					//patch ajax settings to call a progress callback
					$.ajaxSettings.xhr_bak = $.ajaxSettings.xhr;
					$.ajaxSettings.xhr = function() {
						var xhr = $.ajaxSettings.xhr_bak();
						if (this.progress) {
							if (xhr instanceof window.XMLHttpRequest) {
								xhr.addEventListener('progress', this.progress, false);
							}

							if (xhr.upload) {
								xhr.upload.addEventListener('progress', this.progress, false);
							}
						}
						return xhr;
					};
				}

				var ajax = {
					_addCookiesInUrl: function(url) {
						// if(url.indexOf("?")==-1){
						// 	url+="?"
						// }else{
						// 	url+="&"
						// }
						// url += "cors_cookie="+encodeURI(document.cookie);
						return url;
					},
					_ajax: function(url, type, data, success, error, net_error) {
						var jqxhr = $.ajax({
							url: url,
							type: type,
							data: data,
							success: dataFormat(success, error),
							error: net_error,
							progress: function(event) {
								jqxhr.emit("progress", event);
								if (event.loaded == event.total) {
									//释放内存
									eventManager.clear("progress" + _event_prefix);
								}
							},
							xhrFields: {
								withCredentials: true
							},
							xhr: function() {
								var xhr = $.ajaxSettings.xhr();
								if (xhr.upload) {
									xhr.upload.addEventListener('progress', function(event) {
										var percent = 0;
										var position = event.loaded || event.position; /*event.position is deprecated*/
										var total = event.total;
										if (event.lengthComputable) {
											percent = Math.ceil(position / total);
										}
										jqxhr.emit("uploadProgress", event, position, total, percent);
										if (percent >= 1) {
											eventManager.clear("uploadProgress" + _event_prefix);
										}
									}, false);
								}
								return xhr
							}
						});
						var _event_prefix = Math.random();
						//事件机制，目前支持progress
						jqxhr.on = function(eventName) {
							eventName += _event_prefix;
							arguments[0] = eventName;
							return eventManager.on.apply(eventManager, arguments);
						};
						jqxhr.emit = function(eventName) {
							eventName += _event_prefix;
							arguments[0] = eventName;
							return eventManager.fire.apply(eventManager, arguments);
						};
						return jqxhr;
					},
					get: function(url, data, success, error, net_error) {
						url = ajax._addCookiesInUrl(url);
						if (data instanceof Function) {
							net_error = error;
							error = success;
							success = data;
							data = {};
						};
						return ajax._ajax(url, "get", data, success, error, net_error);
					},
					post: function(url, data, success, error, net_error) {
						url = ajax._addCookiesInUrl(url);
						if (data instanceof Function) {
							net_error = error;
							error = success;
							success = data;
							data = {};
						};
						return ajax._ajax(url, "post", data, success, error, net_error);
					},
					put: function(url, data, success, error, net_error) {
						if (data instanceof Function) {
							net_error = error;
							error = success;
							success = data;
							data = {};
						};
						url = ajax._addCookiesInUrl(url);
						return ajax._ajax(url, "put", data, success, error, net_error);
					},
					"delete": function(url, data, success, error, net_error) {
						url = ajax._addCookiesInUrl(url);
						if (data instanceof Function) {
							net_error = error;
							error = success;
							success = data;
							data = {};
						};
						return ajax._ajax(url, "delete", data, success, error, net_error);
					}
				};
				return ajax;
			});

		} else {
			/*
			 * 以及jsonp的跨域请求方式
			 */
			define("coAjax", ["Cookies", "shim_json", "queryString"], function(Cookies, JSON, QueryString) {
				var format_back_data = function(info) {
					var cookies = info.cookies;
					for (var key in cookies) {
						if (cookies.hasOwnProperty(key)) {
							Cookies.set(key, cookies[key]);
						}
					}
				};
				var jsonp = {
					_form_data: function(url, method, data) { //method:GET POST PUT DELETE;data:JSON
						// //更新Cookie解析的缓存
						// Cookies.get();
						var json = JSON.stringify({
							// cookies:Cookies._cache,
							method: method,
							query: (new QueryString(url)).queryHash,
							data: data //
						});
						return url.replace(appConfig.server_url, appConfig.server_url + "jsonp/") + "?_=" + (+new Date) + "&co_data=" + encodeURIComponent(json);
					},
					_cb_funs: {},
					_register: function(cb) {
						var hash = Math.random().toString().substr(2);
						jsonp._cb_funs[hash] = cb;
						return hash;
					},
					get: function(url, data, success, error, net_error) {
						if (data instanceof Function) {
							net_error = error;
							error = success;
							success = data;
							data = {};
						};
						var co_url = jsonp._form_data(url, "get", data);
						require([co_url], dataFormat(success, error), net_error);
						// console.log(co_url);
					},
					post: function(url, data, success, error, net_error) {
						if (data instanceof Function) {
							net_error = error;
							error = success;
							success = data;
							data = {};
						};
						var co_url = jsonp._form_data(url, "post", data);
						require([co_url], dataFormat(success, error), net_error);
						// console.log(co_url);
					},
					put: function(url, data, success, error, net_error) {
						if (data instanceof Function) {
							net_error = error;
							error = success;
							success = data;
							data = {};
						};
						var co_url = jsonp._form_data(url, "put", data);
						require([co_url], dataFormat(success, error), net_error);
						// console.log(co_url);
					},
					"delete": function(url, data, success, error, net_error) {
						if (data instanceof Function) {
							net_error = error;
							error = success;
							success = data;
							data = {};
						};
						var co_url = jsonp._form_data(url, "delete", data);
						require([co_url], dataFormat(success, error), net_error);
						// console.log(co_url);
					}
				}
				return jsonp;
			});
		}
	}());
	define("page_onload", function() {
			var _aNode = document.createElement("a");

			function _get_pathname(pathname) {
				_aNode.href = pathname;
				pathname = _aNode.pathname;
				if (pathname.indexOf("/") !== 0) { //Fuck IE
					pathname = "/" + pathname;
				}
				return pathname;
			};
			var load = {
				_pages: {},
				register: function(pathname, fun) {
					pathname = _get_pathname(pathname);
					load._pages[pathname] = fun;
					if (location.pathname == pathname) {
						load.emit(pathname);
					}
					if (pathname === "/*") {
						load.emit("/*");
					}
				},
				emit: function(pathname) {
					pathname = _get_pathname(pathname);
					var foo = load._pages[pathname];
					if (foo) {
						foo();
					}
					if (pathname !== "/*") {
						load._pages["/*"] && load._pages["/*"]();
					}
				}
			}
			return load;
		})
		/*
		 * 常用地址工具
		 */
	define("href", ["jSouper", "page_onload", "jQuery", "title"], function(jSouper, page_onload, $, title) {
		var href = {
			toLogin: function() {
				// location.href = "http://"+location.host+"/sign_in.html?id=1&cb_url="+encodeURIComponent(location.href);
				href.jump("/sign_in.html?id=1&cb_url=" + encodeURIComponent(location.href))
			},
			toBusLogin: function() {
				// location.href = "http://"+location.host+"/admin-login.html?id=1&cb_url="+encodeURIComponent(location.href);
				href.jump("/admin-login.html?id=1&cb_url=" + encodeURIComponent(location.href))
			},
			toMain: function() {
				// location.href = "http://"+location.host+"/main-beta.html";
				href.jump("/main-beta.html")
			},
			//判定是否在商家管理页面中，用来判断是否需要获取访客信息
			isAdmin: function() {
				return location.pathname === "/admin-beta.html" || location.pathname === "/admin-login.html";
			},
			//判断是否在用户管理页面中
			isUser: function() {
				return location.pathname === "/personal-beta.html" || location.pathname === "/mobile.personal.html"
			},
			//是否是测试版本，注意，不是本地的，是部署上去的测试版
			isDev: function() {
				// var hostMap = {
				// 	"zouliang.dotnar.com": 1,
				// 	"zengwei.dotnar.com": 1,
				// 	"zengqunsheng.dotnar.com": 1,
				// 	"yongyang.dotnar.com": 1,
				// 	"yuyingtang.dotnar.com": 1,
				// 	"d1.dotnar.com": 1,
				// 	"dev.dotnar.com": 1,
				// 	"my.dotnar.com": 1,
				// 	"haitao.dotnar.com": 1
				// };
				var hostMap = {
					"www.cat-fruit.com": 1,
					"www.fuzangtang.com": 1,
					"yunyun": 1,
					"lijin": 1,
					"qinglutang": 1,
					"tibetcheese": 1,
					"zhengwei": 1,
					"xiangyu": 1,
					"dianna": 1,
					// "yingli": 1,
					"xuezi": 1,
					"bangeel": 1,
					"hpgj": 1,
					"amintang1965": 1,
					"qingwenzhen": 1
				};
				//目前只有d1使用测试版在展览，而dev是本地开发必用
				return !(hostMap[location.hostname] || hostMap["www." + location.hostname] || hostMap[location.hostname.replace(".dotnar.com", "")]);
			},
			pathnameFix: function(pathname) {
				return pathname.charAt(0) === "/" ? pathname : ("/" + pathname);
			},
			//微信跳转，获取openid
			wxJump: function(url) {
				alert("努力跳转中……");
				require(["WX", "mobile_jump", "coAjax"], function(WX, mobile_jump, coAjax) {
					url = mobile_jump.parse(url);
					if (url.indexOf("http://") !== 0 && url.indexOf("https://") !== 0) {
						url = location.protocol + "//" + location.host + url;
					}
					coAjax.post(appConfig.other.make_wx_short_url, {
						url: url
					}, function(result) {
						var short_url = result.result;
						var wx_url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=" + wx_config.appId +
							"&redirect_uri=" + encodeURIComponent("http://api.dotnar.com/wx/authorize/notify_url") +
							"&response_type=code&scope=snsapi_userinfo&state=" + encodeURIComponent(window.busInfo ? busInfo._id : appConfig.bus_id + "|" + short_url) +
							"#wechat_redirect";
						location.href = wx_url;
					});
				});
				// return href.jump(url);
			}
		}

		function fire_onlad() {
			window.onmypageload && window.onmypageload();
		}
		if (window.history && history.pushState && false) {
			var _ajax_get_page;
			var first_state = {
				current_url: location.href
			};
			history.replaceState(first_state, document.title);
			var _map_cache = {};
			var ScriptLinkNodeString = /<script[^>]*?src=([\'\"\"])([^\'\"\"]*?)\1[^>]*?>/gi;
			var ScriptNodeString = /<script[^>]*>([\s\S]*?)<\/script>/gi;
			var LinkNodeString = /<link[^>]*?href=([\'\"\"])([^\'\"\"]*?)\1[^>]*?>/gi;
			var BodyNodeString = /<body[^>]*>([\s\S]*?)<\/body>/gi;
			var TitleNodeString = /<title[^>]*>([\s\S]*?)<\/title>/gi;
			var _aNode = document.createElement("a");
			var _aNode_1 = document.createElement("a");
			var mobile_jump;
			href.jump = function(url, no_pushState, method) {
				url = (mobile_jump || (mobile_jump = require("mobile_jump"))).parse(url);
				_aNode.href = url;
				url = _aNode.href;
				var current_state = {
					before_url: location.href,
					current_url: url
				};
				method || (method = "pushState");
				var location_pathname = location.pathname;
				if (no_pushState) {
					_aNode_1.href = no_pushState;
					var location_pathname = _aNode_1.pathname;
				}
				if ((_aNode.pathname === location_pathname) && (!no_pushState) || (_ajax_get_page && _ajax_get_page.__pathname === _aNode.pathname)) {
					//默认的HASH触发
					history[method](current_state, null, url);
					return;
				}
				//缓存当前页面
				var _current_cache = _map_cache[location_pathname] || (_map_cache[location_pathname] = {
					title: document.title,
					app: App
				});
				_current_cache.nodes = Array.prototype.slice.call(document.body.childNodes);
				//获取下一个页面的缓存
				var _next_cache = _map_cache[_aNode.pathname];
				//中断前一个AJAX请求（可能误触）
				if (_ajax_get_page) {
					_ajax_get_page.abort();
				}
				var url = _aNode.href;
				//有缓存就用缓存的，没有就直接请求
				if (_next_cache) {
					!no_pushState && history[method](current_state, "加载中……", url);
					_current_cache.nodes.forEach(function(node) {
						document.body.removeChild(node);
					});

					window.App = _next_cache.app;

					_next_cache.nodes.forEach(function(node) {
						document.body.appendChild(node);
					});
					var jSouperAppNode = document.getElementById("jSouperApp")
					jSouperAppNode && (jSouperAppNode.style.display = "block");

					title(_next_cache.title);
					page_onload.emit(_aNode.pathname);
					return false;
				} else {
					_ajax_get_page = $.ajax({
						url: url,
						type: 'get',
						beforeSend: function() {},
						error: function(request) {},
						success: function(data) {
							!no_pushState && history[method](current_state, "加载中……", url);

							var $cacheHTML = $(data);
							//解析jSouper Body
							var page_vm;
							data.replace(BodyNodeString, function(outerHTML, innerHTML) {
								page_vm = jSouper.parse(innerHTML)(App.getModel());
							});
							if (!page_vm) {
								location.href = url;
							}
							window.App = page_vm;

							//加载JS文件、运行JS嵌套脚本
							var _scriptSrc = []
							data.replace(ScriptLinkNodeString, function(outerHTML, strq, scriptSrc) {
								_scriptSrc.push(scriptSrc);
							});
							// console.log(_scriptSrc);
							var _scriptFoo = []
							data.replace(ScriptNodeString, function(outerHTML, scriptText) {
								if (scriptText.trim()) {
									try {
										_scriptFoo.push(Function(scriptText));
									} catch (e) {
										location.href = url;
									}
								}
							});
							require(_scriptSrc, function() {
								_scriptFoo.forEach(function(foo) {
									try {
										foo()
									} catch (e) {
										location.href = url;
									}
								});
							});
							//加载CSS文件
							data.replace(LinkNodeString, function(outerHTML, strq, linkHref) {
								require(["r_css!" + linkHref]);
							});

							//准备就绪
							_current_cache.nodes.forEach(function(node) {
								document.body.removeChild(node);
							});

							page_vm.append(document.body);
							var jSouperAppNode = document.getElementById("jSouperApp")
							jSouperAppNode && (jSouperAppNode.style.display = "block");

							data.replace(TitleNodeString, function(outerHTML, titleText) {
								title(titleText);
							});
							// page_onload.emit(_ajax_get_page.pathname);//初始化的时候会自动触发
							_ajax_get_page = null;
						}
					});
					_ajax_get_page.__pathname = _aNode.pathname;
				}
				return false;
			}
			window.addEventListener("popstate", function(e) {
				var state = e.state || history.state;
				// console.log(state);
				if (state) {
					href.jump(location.href, state.current_url);
				}
			});
			href.replace = function(url) {
				href.jump(url, null, "replaceState");
			};
		} else {
			href.jump = function(url) {
				var mobile_jump = require(["mobile_jump"], function(mobile_jump) {
					location.href = mobile_jump.parse(url);
				});
			}
			href.replace = href.jump;
		}
		return href;
	});
	/*
	 * 通用的单页HASH路由功能
	 */
	define("hash_routie", ["queryString"], function(QueryString) {
		var USE_CSS_MAP = {};

		function hash_routie(config) {
			var base_HTML_url = config.html_url;
			var base_js_url = config.js_url;
			var common_hash = config.hash_prefix;
			var default_hash = config.default_hash;
			var tele_name = config.teleporter;
			if (config.use_css) {
				USE_CSS_MAP[config.use_css] = {
					load: false,
					css_text: "",
					using: false
				};
			}
			require(["routie", "jSouper"], function(routie, jSouper) {
				/*
				 * HASH路由
				 */
				var _viewModules = {};

				function _routie_common(key) {
					key = hash_routie.get_pathname(key);
					jSouper.ready(function() {
						if (!key) {
							return;
						}
						hash_routie._current_key = key;
						hash_routie._current_path = location.hash.split("#")[1] || "";
						config.before_handle && config.before_handle(key, _viewModules);

						var rightVM = _viewModules[key];

						if (!rightVM) {
							var xmp_url = base_HTML_url + key + ".html";
							showLoader(); //样式表可能已经切换，避免丑陋画面出现
							require(["r_text!" + xmp_url], function(html) {
								_viewModules[key] = rightVM = jSouper.parse(html, xmp_url)(App.getModel());
								App.teleporter(rightVM, tele_name);
								removeLoader();
							});
							require([base_js_url + key]);
						} else {
							App.teleporter(rightVM, tele_name);
							hash_routie.emit(key);
							hash_routie.emit("*");
						}
					});

					for (var _use_css_key in USE_CSS_MAP) {
						if (USE_CSS_MAP.hasOwnProperty(_use_css_key)) {
							(function(use_css_config, _use_css_key) {
								if (_use_css_key == config.use_css) { //匹配成功
									if (!use_css_config.load) { //未下载，直接下载使用并缓存
										use_css_config.load = true; //锁定
										use_css_config.using = true; //锁定
										// debugger
										showLoader();
										require(["r_css!" + _use_css_key], function(css_text) {
											removeLoader()
											use_css_config.css_text = css_text;
										});
									} else if (!use_css_config.using) { //已经下载，直接使用
										// debugger
										addSheet(use_css_config.css_text)
										use_css_config.using = true;
									}
								} else { //不匹配
									if (use_css_config.using) { //如果使用中，进行删除
										// debugger
										removeSheet(use_css_config.css_text);
										use_css_config.using = false;
									}
								}
							}(USE_CSS_MAP[_use_css_key], _use_css_key));
						}
					}
				};
				var routie_config = {};
				routie_config[common_hash] = _routie_common;
				if (default_hash) {
					routie_config["*"] = function(hash) {
						var key = hash_routie.get_pathname(hash);
						if (!key) {
							_routie_common(key || default_hash);
						}
					}
				}
				routie(routie_config);
			});
		}
		_on = {};
		hash_routie.on = function(key, cb) {
			_on[key] = cb;
			(hash_routie._current_key == key || key === "*") && cb(key);
		};
		hash_routie.emit = function(key) {
			var cb = _on[key];
			cb && cb(key);
		};
		hash_routie.get_pathname = function(hash) {
			var index = hash.indexOf("?")
			if (index !== -1) { //如果有参数，过滤参数
				var indexHash = hash.indexOf("#"); //有时候#会在?前面
				if (indexHash !== -1) {
					index = Math.min(indexHash, index);
				}
				hash = hash.substring(0, index);
			}
			return hash;
		};
		hash_routie.get_search = function(hash) {
			var index = hash.indexOf("?")
			if (index !== -1) { //如果有参数，过滤参数
				hash = hash.substr(index + 1);
			}
			return hash;
		};
		hash_routie.hash = function(hashMap, clear) {
			if (!clear) {
				var queryString = new QueryString(location.hash);
				var queryHash = queryString.queryHash;
				//和原有HASH变量进行混合
				for (var key in queryHash) {
					if (queryHash.hasOwnProperty(key) && !hashMap.hasOwnProperty(key)) {
						hashMap[key] = queryHash[key];
					}
				}
			}
			var hash_str = "";
			for (var key in hashMap) {
				if (hashMap.hasOwnProperty(key)) {
					hash_str += "&" + key + "=" + encodeURIComponent(hashMap[key]);
				}
			}
			hash_str = hash_str.replace("&", "?");
			location.hash = hash_routie.get_pathname(location.hash.substr(1)) + hash_str;
		}
		return hash_routie;
	});

}());
/*通用翻页函数*/
define("jSouper_page", ["common", "hash_routie", "queryString"], function(jSouper, hash_routie, QueryString) {
	var _default_num = 10;
	var queryString = new QueryString();

	function _init() {
		var App = jSouper.App;
		App.set("$Event.__common__.pre_page", function(e, vm) {
			//被禁用
			var self = $(this);
			if (self.hasClass("disabled")) {
				return;
			}
			var _page = self.attr("jsouper-p-page");
			if (!_page) {
				queryString.init(location.hash);
				_page = ~~queryString.get("page") - 1 || 0;
			}
			var _num = self.attr("jsouper-p-num") || _default_num;

			hash_routie.hash({
				num: _num,
				page: _page
			});
		});
		App.set("$Event.__common__.next_page", function(e, vm) {
			//被禁用
			var self = $(this);
			if (self.hasClass("disabled")) {
				return;
			}
			var _page = self.attr("jsouper-p-page");
			if (!_page) {
				queryString.init(location.hash);
				_page = ~~queryString.get("page") + 1;
			}
			var _num = self.attr("jsouper-p-num") || _default_num;

			hash_routie.hash({
				num: _num,
				page: _page
			});
		});
		App.set("$Event.__common__.change_page", function(e, vm) {
			//被禁用
			var self = $(this);
			if (self.hasClass("disabled")) {
				return;
			}
			var _page = +self.attr("jsouper-p-page");
			if (isNaN(_page)) {
				console.log("分页参数错误");
				return;
			}
			var _num = self.attr("jsouper-p-num") || _default_num;

			hash_routie.hash({
				num: _num,
				page: vm.get("$Index")
			});
		});
		//仅仅初始化一次
		_init = function() {};
	}

	function _jSouper_page() {
		_init();
	}
	return _jSouper_page;
});
/*confirm ; prompt*/
;
(function() {
	var _confirm = window.confirm;
	window.myConfirm = function(str, cb_true, cb_false) {
		if (_confirm(str)) {
			cb_true && cb_true();
		} else {
			cb_false && cb_false();
		}
	}
	var _prompt = window.prompt;
	window.myPrompt = function(str, default_value, cb_true, cb_false) {
		if (default_value instanceof Function) {
			cb_false = cb_true;
			cb_true = default_value;
			default_value = "";
		}
		var res = _prompt(str, default_value);
		if (typeof res === "string") {
			cb_true && cb_true(res);
		} else {
			cb_false && cb_false();
		}
	}
}());
/*
 * 手机端跳转
 */
if (window._isStore || window._isWWW || window._isBus) {
	var mobile_jump_deps = ["href", "hash_routie"];
	mobile_jump_deps.push("appConfig");
	define("mobile_jump", mobile_jump_deps, function(href, hash_routie) {
		//手机端正确跳转
		/*!href.isDev() ? {
			"/admin-login.html": "/m.admin-login.html",
			"/admin-beta.html": "/m.admin.html",
			"/all-goods-beta.html": "/m.all-goods.html",
			"/cart-beta.html": "/m.cart.html",
			"/goods-details.html": "/m.goods-details.html",
			"/help.html": "/m.help.html",
			"/sign_in.html": "/m.login.html",
			"/": "/m.main.html",
			"/main-beta.html": "/m.main.html",
			"/pay.beta.html": "/m.pays.html",
			"/personal-beta.html": "/m.personal.html",
			"/store-int.html": "/m.store-int.html"
		} :*/
		if (window._isStore) {
			var _mobile_page_map = {
				"/all-goods-beta.html": "/mobile.main.html#default/goods_list",
				"/cart-beta.html": "/mobile.main.html#default/cart",
				"/goods-details.html": "/mobile.main.html#default/goods_details",
				"/help.html": "/mobile.main.html#default/help",
				"/pay.beta.html": "/mobile.main.html#default/pay",
				"/personal-beta.html": "/mobile.personal.html",
				"/store-int.html": "/mobile.main.html#default/soreinfo",
				"/": "/mobile.main.html",
				"/main-beta.html": "/mobile.main.html",
				"/catering.main.html": "/mobile.main.html",
				"/tags.html": "/mobile.main.html#default/tags",
				"/sign_in.html": "/mobile.main.html#default/sign_in"
			};
			var mobile_main_urls = [];
			for (var i in _mobile_page_map) {
				var url_str = _mobile_page_map[i];
				if (url_str.indexOf("/mobile.main.html") !== -1) {
					mobile_main_urls.push(url_str);
				}
			}
			try {
				var mobile_theme_name = appConfig.site_info.permission.data_mobile_theme_name
			} catch (e) {
				mobile_theme_name = "普通单排"
			}
			if (mobile_theme_name == "普通双排") {
				//电脑版跳转到index
				for (var i in _mobile_page_map) {
					_mobile_page_map[i] = _mobile_page_map[i].replace("/mobile.main.html", "/mobile.index.html");
				}
				//手机版main跳转到index
				for (var i = 0; url_str = mobile_main_urls[i]; i += 1) {
					_mobile_page_map[url_str] = url_str.replace("/mobile.main.html", "/mobile.index.html");
				}
			} else if (mobile_theme_name == "普通单排") { //普通单排
				//手机版index跳转到main
				for (var i = 0; url_str = mobile_main_urls[i]; i += 1) {
					_mobile_page_map[url_str.replace("/mobile.main.html", "/mobile.index.html")] = url_str;
				}
			} else if (mobile_theme_name == "餐饮行业") {
				//电脑版跳转到catering
				for (var i in _mobile_page_map) {
					_mobile_page_map[i] = _mobile_page_map[i].replace("/mobile.main.html", "/catering.mobile.html");
				}
				//手机版main跳转到catering
				for (var i = 0; url_str = mobile_main_urls[i]; i += 1) {
					_mobile_page_map[url_str] = url_str.replace("/mobile.main.html", "/catering.mobile.html");
				}
			}
		}
		if (_isWWW) {
			var _mobile_page_map = {
				"/": "/m.dotnar.html",
				"/dotnar.main.html": "/m.dotnar.html"
			}
		}
		if (_isBus) {
			var _mobile_page_map = {
				"/": "/mobile.admin.html",
				"/admin-login.html": "/mobile.admin-login.html",
				"/admin-beta.html": "/mobile.admin.html"
			}
		}

		//反向到PC
		var _pc_page_map;

		mobile_jump.init = function(_mobile_page_map) {
			_pc_page_map = {};
			for (var i in _mobile_page_map) {
				_mobile_page_map.hasOwnProperty(i) && (_pc_page_map[_mobile_page_map[i]] = i);
			}
		};
		mobile_jump.init(_mobile_page_map);

		function mobile_jump() {
			console.log("mobile_jump");
			var to_url = mobile_jump.parse(location.href);
			_aNode.href = to_url;
			// confirm(href.pathnameFix(_aNode.pathname) + href.pathnameFix(location.pathname))
			if (href.pathnameFix(_aNode.pathname) !== href.pathnameFix(location.pathname)) {
				href.replace(to_url);
			}
		}
		var _aNode = document.createElement("a");
		mobile_jump.parse = function(to_url) {
			_aNode.href = to_url;
			var _a_pathname = href.pathnameFix(_aNode.pathname);
			if (_aNode.hostname !== location.hostname) {
				return to_url;
			}
			//过滤掉http:~.com的部分
			if (to_url.indexOf("http://" + location.host) === 0) {
				to_url = to_url.replace("http://" + location.host, "");
			} else if (to_url.indexOf("https://" + location.host) === 0) {
				to_url = to_url.replace("https://" + location.host, "");
			}
			to_url = href.pathnameFix(to_url)
				//手机版本的是用HASH替代path #asdadasdasd?xxxxx ，获取#~?的那部分
			var pathname_hash = hash_routie.get_pathname(_aNode.hash.substr(1));
			if (_isMobile) {
				if (pathname_hash && (mobile_page = _mobile_page_map[_a_pathname + pathname_hash])) {
					to_url = mobile_page + _aNode.search ? (_aNode.search + "&") : "" + _aNode.hash.replace(pathname_hash, "").replace(/\&amp\;/g, "&")
				} else if (mobile_page = _mobile_page_map[_a_pathname]) {
					to_url = mobile_page + _aNode.search + _aNode.hash;
				}
			} else {
				if (pathname_hash && (pc_page = _pc_page_map[_a_pathname + hash_routie.get_pathname(_aNode.hash)])) {
					to_url = pc_page + (_aNode.search ? (_aNode.search + "&") : "") + _aNode.hash.replace(hash_routie.get_pathname(_aNode.hash), "").replace(/\&amp\;/g, "&")
				} else if (pc_page = _pc_page_map[_a_pathname]) {
					to_url = pc_page + _aNode.search + _aNode.hash;
				}
			}
			return to_url;
		}
		return mobile_jump;
	});
	require(["mobile_jump"], function(mobile_jump) {
		//直接跳转，不等onload
		mobile_jump();
	});
};


define("serverNotify", ["SockJS", "dataFormat", "coAjax"], function(SockJS, dataFormat, coAjax) {
	var conns = {};
	return function _init_sock(type, event_cache, _is_cover) {
		type || (type = "user"); //默认是user类型
		if (conns[type] && !_is_cover) { //同类型只能有一个sock连接
			return conns[type];
		}
		event_cache || (event_cache = {});
		var exports = {
			_send_queue: function() {
				for (var i = 0, data; data = _send_queue[i]; i += 1) {
					sock.send(JSON.stringify(data));
				}
				_send_queue = [];
			},
			send: function(type, value) {
				// if (arguments.length == 1) {
				// 	value = type;
				// }
				var data = {
					type: type,
					value: value
				}
				_send_queue.push(data)
				if (_is_opened) {
					this._send_queue();
				}
			},
			on: function(eventName, fun) {
				var event_col = event_cache[eventName] || (event_cache[eventName] = []);
				event_col.push(fun);
			},
			off: function(eventName) {
				event_cache[eventName] = [];
			},
			emit: function(eventName, value) {
				var event_col = event_cache[eventName];
				if (event_col) {
					event_col.forEach(function(fun) {
						fun(value)
					});
				}
			}
		};
		var sock = new SockJS(appConfig.socketNotify);
		var _is_opened = false;
		var _send_queue = [];
		sock.onopen = function() {
			console.log('+Sock 连接已经打开');
			_is_opened = true;
			exports._send_queue();
			//获取连接密匙
			console.log("Sock 获取协议密匙");
			coAjax.post(appConfig.socketNotify_key, {
				type: type
			}, function(result) {
				console.log("Sock 密匙获取成功，申请通讯权限");
				var s_key = result.result.s_key;
				exports.send("init", {
					s_key: s_key
				});
				exports.on("init-success", function() {
					console.log("Sock 申请通讯权限申请成功");
					alert("success", "连接已建立");
				});
				exports.on("init-error", function(errorMsg) {
					alert("error", errorMsg);
				});
			});
		};
		var data_handle = dataFormat(function(result) {
			exports.emit(result.type, result.result)
		}, function(errorCode, xhr, errorMsg, result) {
			exports.emit(result.type + "-error", result.toString)
		});
		sock.onmessage = function(e) {
			console.log('message', e.data);
			try {
				var data = JSON.parse(e.data);
				data_handle(data);
			} catch (e) {
				console.error(e);
				exports.emit("error", e.data);
			}
		};
		sock.onclose = function() {
			// console.log('close');
			console.log('-Sock 连接已经断开');
			alert("warn", "与服务器的连接断开");
			exports.off("init-success");
			exports.off("init-error");
			setTimeout(function() {
				_init_sock(type, event_cache, true);
			}, 500); //半秒后进行重连
		};
		return (conns[type] = exports);
	}
});

define("eventManager", function() {
	var _eventCache = {};
	var _eventMap = {};
	var eventManager = {
		is: function(check_obj, eventName, handle, rejectHandle) {
			if (check_obj) {
				handle();
			} else {
				eventManager.on(eventName, handle, rejectHandle);
			}
		},
		on: function(eventName, handle, rejectHandle) {
			var eventList = _eventCache[eventName] || (_eventCache[eventName] = []);
			var _id = Math.random().toString(36).substring(2);
			eventList.push(_eventMap[_id] = {
				_id: _id,
				handle: handle,
				rejectHandle: rejectHandle
			});
			return _id;
		},
		off: function(eventName, _id) {
			if (arguments.length === 1) {
				_id = eventName;
				var eventObj = _eventMap[_id];
				eventObj.handle = null;
			} else if (_eventCache.hasOwnProperty(eventName)) {
				var eventList = _eventCache[eventName];
				for (var i = 0, eventObj; eventObj = eventList[i]; i += 1) {
					if (eventObj._id == _id) {
						eventObj.handle = null;
						eventObj.rejectHandle = null;
					}
				}
			}
		},
		fire: function(eventName) {
			var args = Array.prototype.slice.call(arguments, 1);
			if (_eventCache.hasOwnProperty(eventName)) {
				var eventList = _eventCache[eventName];
				for (var i = 0, eventObj; eventObj = eventList[i]; i += 1) {
					eventObj.handle && eventObj.handle.apply(eventObj, args);
				}
			}
		},
		reject: function(eventName) {
			if (_eventCache.hasOwnProperty(eventName)) {
				var eventList = _eventCache[eventName];
				for (var i = 0, eventObj; eventObj = eventList[i]; i += 1) {
					eventObj.rejectHandle && eventObj.rejectHandle.apply(eventObj, args);
				}
			}
		},
		clear: function(eventName) {
			if (_eventCache.hasOwnProperty(eventName)) {
				var eventList = _eventCache[eventName];
				for (var i = 0, eventObj; eventObj = eventList[i]; i += 1) {
					_eventMap[eventObj._id] = null;
				}
				eventList.length = 0;
			}
		}
	};
	eventManager.emit = eventManager.fire;
	eventManager._eventCache = _eventCache;
	eventManager._eventMap = _eventMap;
	return eventManager;
});
define("versionManage", function(argument) {
	return function(version_name, moduleName) {
		/*
		 * 版本管理
		 */
		//获取当前版本号
		var _version_key = "appConfig.version." + version_name;
		var _version = LS.get(_version_key);
		var _new_version = appConfig.version[version_name];
		// confirm(["当前版本号：", _version, appConfig.version.o2o_version]);
		//将最新的版本号写入缓存中，并确保这个版本号不可为空，方便下次判断
		LS.set(_version_key, _new_version || +new Date);
		//判断当前版本号与最新版本号的异同（PS：非开发模式下才需要此判断）
		if (_version && (_version != _new_version) && !_isDev) {
			//版本号不同，清除所有缓存
			LS.removeByPrefix("r_text!");
			//并重载页面
			// confirm("发现新版本，马上使用！");
			location.reload();
		};
		//清除缓存配置文件信息，这是没用的
		LS.removeByPrefix("r_text!" + require.toUrl(moduleName).split("?")[0]);
	}
});
/*微信核心*/
define("WX", ["wx_core", "coAjax", "queryString"], function(wx, coAjax, queryString) {
	var fun_list = [];
	var ready = false;

	var qs = new queryString;
	wx_bus_id = qs.get("wx_bus_id");
	if (!wx_bus_id) {
		wx_bus_id = window.busInfo ? busInfo._id : appConfig.bus_id
	}

	coAjax.get(appConfig.wx.jsapi_signature, {
		wx_bus_id: wx_bus_id
	}, function(result) {
		var config = result.result;
		console.log(config);
		config.debug = false;
		config.jsApiList = [
			'checkJsApi',
			'onMenuShareTimeline',
			'onMenuShareAppMessage',
			'onMenuShareQQ',
			'onMenuShareWeibo',
			'hideMenuItems',
			'showMenuItems',
			'hideAllNonBaseMenuItem',
			'showAllNonBaseMenuItem',
			'translateVoice',
			'startRecord',
			'stopRecord',
			'onRecordEnd',
			'playVoice',
			'pauseVoice',
			'stopVoice',
			'uploadVoice',
			'downloadVoice',
			'chooseImage',
			'previewImage',
			'uploadImage',
			'downloadImage',
			'getNetworkType',
			'openLocation',
			'getLocation',
			'hideOptionMenu',
			'showOptionMenu',
			'closeWindow',
			'scanQRCode',
			'chooseWXPay',
			'openProductSpecificView',
			'addCard',
			'chooseCard',
			'openCard'
		];
		wx.config(config);
		window.wx_config = config;
		window.wx = wx;
		wx.ready(function() {
			alert("success", "微信验证通过");
			ready = true;
			wx_fun();
		});
		wx.error(function(err) {
			alert("error", "微信验证失败")
			alert("error", JSON.stringify(err))
		});
	});

	function wx_fun(fun) {
		if (fun instanceof Function) {
			fun_list.push(fun)
		}
		if (ready) {
			for (var i = 0, fun; fun = fun_list[i]; i += 1) {
				fun(wx);
			}
			fun_list.length = 0;
		}
	}
	return wx_fun
});
define("windowScroll", ["jQuery", "eventManager"], function($, eventManager) {
	var self = $(window);
	var _top = 0;
	var _event_name = Math.random().toString(32) + "|scroll";
	self.scroll(function(e) {
		var _current_top = self.scrollTop()
		e.deltaY = _current_top - _top;
		_top = _current_top;
		eventManager.emit(_event_name, e)
	});
	return function windowScroll(foo) {
		eventManager.on(_event_name, foo);
	}
});

define("dataAnimate", function() {
	var _dataAnimate_id = "dataAnimate_" + Math.random().toString(36).substr(2);

	function data_animate(cb, fps) {
		if (cb[_dataAnimate_id]) {
			return
		}
		cb[_dataAnimate_id] = true;
		var args = null;
		var old_args = null;
		var context = null;
		var _ti;
		(fps = ~~fps) || (fps = 5);
		var args_length; //每一个参数的步长
		function animate_handle() {
			args = Array.prototype.slice.call(arguments);
			context = this;
			if (old_args) {
				clearInterval(_ti);
				var fps_index = 0;
				//计算每一个参数的步长
				args_length = {
					argsIndex: []
				};
				for (var i = 0, len = args.length; i < len; i += 1) {
					if (typeof args[i] === "number" && typeof old_args[i] === "number") {
						args_length.argsIndex.push(i);
						args_length[i] = (args[i] - old_args[i]) / fps;
					}
				}
				_ti = setInterval(function _ani() {
					fps_index += 1;
					if (fps_index == fps) {
						//最后一帧，使用原本数据，确保不被小数溢出英雄
						old_args = args;
						cb.apply(context, args);
						clearInterval(_ti);
						return;
					}
					for (var i = 0, len = args_length.argsIndex.length; i < len; i += 1) {
						var arg_index = args_length.argsIndex[i];
						var arg_loop = args_length[arg_index];
						old_args[arg_index] += arg_loop;
					}
					cb.apply(context, old_args);
					return _ani;
				}(), 1000 / 60);
			} else {
				old_args = args;
				cb.apply(context, args);
			}
		};

		animate_handle.dataAnimateStop = cb.dataAnimateStop = function() {
			clearInterval(_ti);
			if (args && old_args !== args) {
				old_args = args;
				cb.apply(context, args);
			}
		};
		animate_handle.dataAnimateReset = cb.dataAnimateReset = function(_fps) {
			animate_handle.dataAnimateStop();
			old_args = null;
			args = null;
			_fps && (fps = ~~_fps);
			fps || (fps = 5);
		}

		return animate_handle;
	};
	return data_animate;
});

define("Locker", function() {
	function Locker(unlock_emit) {
		if (!(this instanceof Locker)) {
			return new Locker(unlock_emit)
		}
		this.unlock_emit = unlock_emit || function() {};
		this.lock_map = {};
	};
	//num必须是整数，小数的话可能导致JS运算精度丢失的问题
	Locker.prototype.addLock = function(key, num) {
		(num = ~~num) || (num = 1);
		var lock_item = this.lock_map[key] || (this.lock_map[key] = 0);
		return this.lock_map[key] += num;
	};
	Locker.prototype.removeLock = function(key, num) {
		(num = ~~num) || (num = 1);
		var lock_item = this.lock_map[key] || 0;
		this.lock_map[key] = lock_item = lock_item - num;
		if (lock_item <= 0) {
			delete this.lock_map[key];
			var _run_unlock_emit = false;
			for (var _k in this.lock_map) {
				if (this.lock_map.hasOwnProperty(_k)) {
					_run_unlock_emit = true;
					break;
				}
			}
			if (!_run_unlock_emit) {
				this.unlock_emit();
			}
		}
	};

	return Locker;
});